'use strict';

const ERR_CODE = require('../constants/errorCode');
const ALBUM_TABLE = 'album';
const PICTURE_TABLE = 'picture';
const RECYCLER_TABLE = 'recycler';

const Service = require('egg').Service;

class AlbumService extends Service {
  async create(userId, name, description, isDefalutAlbum) {
    const { ctx, app } = this;
    // 新建事务
    const conn = await app.mysql.beginTransaction();

    try {
      // 第一步：检查相册名是否被使用
      const result1 = await app.mysql.select(ALBUM_TABLE, {
        where: { name, user_id: userId },
        orders: [
          [ 'album_id', 'asc' ],
        ],
        limit: 1,
        offset: 0,
      });
      if (result1.length >= 1) throw (ERR_CODE.AlbumCreate_DuplicateName);

      // 第二步：没有被使用的话就新建这个相册
      const result2 = await conn.insert(ALBUM_TABLE, {
        user_id: userId,
        name,
        description,
        is_default_album: isDefalutAlbum, // 1: 是默认相册 0:不是默认相册
        create_time: app.mysql.literals.now,
        update_time: app.mysql.literals.now,
      });
      if (result2.affectedRows !== 1) throw (ERR_CODE.AlbumCreate_DBInsertFail);

      // 提交事务
      await conn.commit();

      // 返回相册ID
      return result2.insertId;
    } catch (err) {
      // 回滚事务
      await conn.rollback();

      // 处理异常
      switch (err) {
        case ERR_CODE.AlbumCreate_DuplicateName:
          ctx.throw(422, '相册创建失败，相册名称重复', {
            errCode: ERR_CODE.AlbumCreate_DuplicateName,
            description: '相册名称重复',
          });
          break;
        case ERR_CODE.AlbumCreate_DBInsertFail:
          ctx.throw(422, '相册创建失败，数据库插入失败', {
            errCode: ERR_CODE.AlbumCreate_DBInsertFail,
            description: '数据库插入失败',
          });
          break;
        default:
          throw (err);
      }
    }
  }

  async info(albumId) {
    const { app } = this;
    const result = await app.mysql.get(ALBUM_TABLE, { album_id: albumId });
    return result;
  }

  async index(userId) {
    const { app } = this;
    const sql = `SELECT l.album_id,l.name, l.description, l.is_default_album ,r.cover_link, r.size, l.create_time, l.update_time FROM ${ALBUM_TABLE} AS l LEFT JOIN (SELECT album_id, file_link AS cover_link, COUNT(*) AS size FROM (SELECT * FROM ${PICTURE_TABLE} WHERE status != '1' ORDER BY create_time DESC) AS k GROUP BY album_id) AS r ON l.album_id = r.album_id WHERE user_id = '${userId}' ORDER BY l.create_time DESC;`;
    const result = await app.mysql.query(sql);
    return result;
  }

  async edit(updateInfo) {
    const { ctx, app } = this;
    // 新建事务
    const conn = await app.mysql.beginTransaction();

    try {
      // 更新相册信息
      const row = {
        ...updateInfo,
        update_time: app.mysql.literals.now,
      };
      const options = {
        where: {
          album_id: updateInfo.album_id,
        },
      };
      const result = await conn.update(ALBUM_TABLE, row, options);
      if (result.affectedRows !== 1) throw (ERR_CODE.AlbumUpdate_DBUpdateFail);

      // 提交事务
      await conn.commit();

      // 返回结果
      return true;
    } catch (err) {
      // 回滚事务
      await conn.rollback();
      // 处理异常
      switch (err) {
        case ERR_CODE.AlbumUpdate_DBUpdateFail:
          ctx.throw(422, '相册信息更新失败', {
            errCode: ERR_CODE.AlbumUpdate_DBUpdateFail,
            description: '数据库更新失败',
          });
          break;
        default:
          throw (err);
      }
    }
  }

  // 删除相册，把相册内所有照片放入回收站
  async destory(userId, albumId) {
    const { ctx, app } = this;
    // 新建事务
    const conn = await app.mysql.beginTransaction();

    try {
      // 第一步：获取默认相册id
      const result1 = await app.mysql.select(ALBUM_TABLE, {
        columns: [ 'album_id' ],
        where: { user_id: userId, is_default_album: 1 },
        orders: [
          [ 'album_id', 'asc' ],
        ],
        limit: 1,
        offset: 0,
      });
      if (result1.length !== 1) throw (ERR_CODE.AlbumDestroy_NoDefaultAlbum);
      if (result1[0].album_id === parseInt(albumId)) throw (ERR_CODE.AlbumDestroy_CannotDeleteDefaultAlbum);

      // 第二步：将该相册的所有照片加入到回收站中
      const result2 = await conn.select(PICTURE_TABLE, {
        where: { album_id: albumId },
        columns: [ 'pic_id' ],
      });
      const values = [];
      result2.forEach(item => {
        values.push({
          user_id: userId,
          pic_id: item.pic_id,
          create_time: app.mysql.literals.now,
        });
      });
      if (values.length > 0) { await conn.insert(RECYCLER_TABLE, values); }

      // 第三步：将该相册照片合并到默认相册，并将status设置为1（已删除）
      const row = {
        album_id: result1[0].album_id,
        status: 1,
        update_time: app.mysql.literals.now,
      };
      const options = {
        where: {
          album_id: albumId,
        },
      };
      if (values.length > 0) { await conn.update(PICTURE_TABLE, row, options); }

      // 第四步：删除相册
      await conn.delete(ALBUM_TABLE, { album_id: albumId });
      // 提交事务
      await conn.commit();

      return true;
    } catch (err) {
      // 回滚事务
      await conn.rollback();
      // 处理异常
      switch (err) {
        case ERR_CODE.AlbumDestroy_NoDefaultAlbum:
          ctx.throw(422, '无默认相册', {
            errCode: ERR_CODE.AlbumDestroy_NoDefaultAlbum,
            description: '数据库获取失败',
          });
          break;
        case ERR_CODE.AlbumDestroy_CannotDeleteDefaultAlbum:
          ctx.throw(422, '默认相册无法删除', {
            errCode: ERR_CODE.AlbumDestroy_CannotDeleteDefaultAlbum,
            description: '默认相册无法删除',
          });
          break;
        default:
          throw (err);
      }
    }
  }

  async unit(originAlbumId, targetAlbumId) {
    const { app } = this;
    const row = {
      album_id: targetAlbumId,
    };

    const options = {
      where: {
        album_id: originAlbumId,
      },
    };
    await app.mysql.update(PICTURE_TABLE, row, options);
    // 提交事务
    return true;
  }

  async getDefaultAlbum(userId) {
    const { app } = this;
    const result = await app.mysql.select(ALBUM_TABLE, {
      where: { user_id: userId, is_default_album: 1 },
      columns: [ 'album_id' ],
    });
    return result[0].album_id;
  }
}

module.exports = AlbumService;
